#pragma once

#include <string>
#include <stdio.h>


#include "noncopyable.h"


enum LogLevel
{
    INFO,         // 普通信息
    ERROR,        // 错误信息
    FATAL,        // core信息
    DEBUG,        // 调试信息
};

// LOG_INFO("%s, %d", args1, args2)
#define LOG_INFO(LogmsgFormat, ...)  \
  do{                                  \
     Logger & logger = Logger::instance();                                  \
     logger.setLogLevel(LogLevel::INFO);                                     \
     char buf[1024] = {0};                                                   \
     snprintf(buf, 1024, LogmsgFormat, ##__VA_ARGS__);                         \
     logger.log(buf) ;                                                           \
    }while(0)                            \

#define LOG_FATAL(LogmsgFormat, ...)  \
do{                                  \
    Logger & logger = Logger::instance();                                  \
    logger.setLogLevel(LogLevel::FATAL);                                     \
    char buf[1024] = {0};                                                   \
    snprintf(buf, 1024, LogmsgFormat, ##__VA_ARGS__);                         \
    logger.log(buf) ;                                                    \
    exit(-1);                                                        \
    }while(0)                            \
// 只有在定义 MUDEBUG 后之后这个才会开启
#ifdef MUDEBUG
    #define LOG_DEBUG(LogmsgFormat, ...)  \
        do{                                  \
            Logger & logger = Logger::instance();                                  \
            logger.setLogLevel(LogLevel::DEBUG);                                     \
            char buf[1024] = {0};                                                   \
            snprintf(buf, 1024, LogmsgFormat, ##__VA_ARGS__);                         \
            logger.log(buf) ;                                                           \
            }while(0)                            \
#else
    #define LOG_DEBUG(LogmsgFormat, ...)
#endif

#define LOG_ERROR(LogmsgFormat, ...)  \
    do{                                  \
        Logger & logger = Logger::instance();                                  \
        logger.setLogLevel(LogLevel::ERROR);                                     \
        char buf[1024] = {0};                                                   \
        snprintf(buf, 1024, LogmsgFormat, ##__VA_ARGS__);                         \
        logger.log(buf) ;                                                           \
        }while(0)                            \


class Logger : noncopyable{
public:
    // 获取日志唯一的实例对象
    static Logger& instance();

    void setLogLevel(LogLevel level);
    void log(std::string msg);

private:
    LogLevel logLevel_;
};